import numpy, math

def normalize(data):

	# find the bias to make all points positive
	shift = 999999.0
	for i in range(len(data)):
		if data[i][1] < shift:
			shift = data[i][1]
	shift = abs(shift)

	# apply the bias
	for i in range(len(data)):
		data[i][1] = (data[i][1] + shift) 

	# find the max y value 
	max_value = -999999.9
	for i in range(len(data)):
		if abs(data[i][1]) > max_value:
			max_value = data[i][1]

	# normalize the y points
	for i in range(len(data)):
		data[i][1] = data[i][1] / (2 * max_value)

	return data


def generate_linear_data(num_examples):
	data = []
	angle = 0.78 # 45 deg
	bias = 4.0
	start = -0.5
	end = 0.5
	delta = (end - start) / float(num_examples - 1)

	# create the data points
	for i in range(num_examples):
		x = start + i * delta
		y = (angle * x + bias) + numpy.random.normal(0.0, 0.1)
		data.append([x, y])

	return data


def generate_senoidal_data(num_examples):
	data = []
	start = -5
	end = 5
	delta = (end - start) / float(num_examples - 1)

	# create the data points
	for i in range(num_examples):
		x = start + i * delta
		y = math.sin(x) + numpy.random.normal(0.0, 0.1)
		data.append([x, y])

	return data


def generate_sigmoidal_data(num_examples):
	data = []
	start = -5
	end = 5
	delta = (end - start) / float(num_examples - 1)

	# create the data points
	for i in range(num_examples):
		x = start + i * delta 
		y = 1.0 / (1 + math.exp(-x)) 
		data.append([x, y]) 

	return data

def generate_hard_data(num_examples):
	data = []
	start = -10
	end = 10
	delta = (end - start) / float(num_examples - 1)

	# create the data points
	for i in range(num_examples):
		x = start + i * delta 
		y = math.sin(5.0 * x) * x * 5.0
		data.append([x, y]) 

	return data

def print_data(data):
	for i in range(len(data)):
		print data[i][0], data[i][1] + 0.2


if __name__ == "__main__":
	# data = generate_linear_data(20)
	# data = generate_senoidal_data(100)
	# data = generate_sigmoidal_data(10)
	data = generate_hard_data(1000)
	data = normalize(data)
	print_data(data)


